<template>
  <h2>Child子集组件</h2>
  <h3>{{ msg }}</h3>
  <button @click="emitxxx">分发事件</button>
  <!-- <h3>count：{{ count }}</h3> -->
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
  name: 'Child',
  props: ['msg'],
  // setup 的细节问题
  // setup是在beforeCreate生命周期回调之前就执行了，而且就只执行一次，this无法使用
  // 不能通过this调用data/computed/method/props中的相关内容
  // 其实所有的composition API相关回调函数中也都不可以

  // setup中的返回值是一个对象，内部的属性和方法是给html模板使用的
  // setup中的对象内部的属性和data函数中的return对象的属性都可以在html模板中使用
  // setup中的对象中的属性和data函数中的对象中的属性会合并为组件对象的属性
  // setup中的对象中的方法和methods对象中的方法会合并为组件对象的方法
  // 在vue3中尽量不要混合的使用data和setup及methods和setup
  // 一般不要混合使用: methods中可以访问setup提供的属性和方法, 但在setup方法中不能访问data和methods
  // setup不能是一个async函数: 因为返回值不再是return的对象, 而是promise, 模板看不到return对象中的属性数据

  // beforeCreate() {
  //   console.log('beforeCreate执行了')
  // },
  // setup(props, context) {
  setup(props, { attrs, emit, slots }) {
    // props参数，是一个对象，里面有父级组件向子级组件传递的数据，并且是在子级组件中使用props接收到的所有属性
    // console.log(props.msg)
    // context参数，是一个对象，里面有attrs对象（获取当前组件标签上在props中没有声明所有属性的对象），emit方法（分发事件），slots对象（插槽）
    // console.log(context.attrs)
    // console.log(context.emit)

    console.log('setup执行了')
    const showMsg1 = () => {
      console.log('setup中的showMsg方法')
    }

    function emitxxx() {
      // context.emit('xxx', '++')
      emit('xxx', '++')
    }
    return {
      showMsg1,
      emitxxx
      // setuo 中一般都是返回一个对象，对象中的属性和方法都可以在html模板中直接使用
    }
  }
  // data() {
  //   return {
  //     count: 10
  //   }
  // },
  // mounted() {
  //   console.log(this)
  // },
  // methods: {
  //   showMsg2() {
  //     console.log('methods中的showMsg方法')
  //   }
  // }
})
</script>
